package com.nhjf.admin.controller.system;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.code.kaptcha.Producer;
import com.nhjf.admin.common.util.IPTool;
import com.nhjf.admin.common.util.MD5;
import com.nhjf.admin.common.util.StringUtil;
import com.nhjf.admin.common.util.SysProperties;
import com.nhjf.admin.controller.BaseController;
import com.nhjf.admin.system.Constants;
import com.nhjf.admin.util.Encrypt;
import com.nhjf.admin.util.Jurisdiction;
import com.nhjf.common.util.xss.JsoupXssHtml;
import com.nhjf.model.system.AdminSession;
import com.nhjf.model.system.Resource;
import com.nhjf.model.system.Role;
import com.nhjf.model.system.User;
import com.nhjf.pojo.qo.system.AdminSessionQo;
import com.nhjf.pojo.qo.system.ResourceQo;
import com.nhjf.pojo.qo.system.UserQo;
import com.nhjf.service.system.AdminSessionService;
import com.nhjf.service.system.ResourceService;
import com.nhjf.service.system.UserService;

/**
 * @类功能说明：登录
 */
@Controller
@RequestMapping(value = "/login")
public class LoginController extends BaseController {

    private static final String LM_SESSION_VALID_CODE_KEY = "_LM_SESSION_VALID_CODE_";

    @Autowired
    private Producer captchaProducer;

    @Autowired
    private UserService userService;
    @Autowired
    private ResourceService resourceService;
//    @Autowired
//	private MonitorOrderService monitorOrderService;
    @Autowired
    private AdminSessionService adminSessionService;
    static String salts="xHellxo110xadmin";
    /**
     * 
     * @方法功能说明：
     * @修改内容：
     * @参数：
     * @return:
     * @throws
     */
    @RequestMapping
    public String index(HttpServletRequest request, Model model,@RequestParam(value="error", required=false) String error){
        String msg="";
        if("1".equals(error)){
            msg="验证码错误！";
        }else if("2".equals(error)){
            msg="用户名或密码错误！";
        }else if("3".equals(error)){
            msg="该用户已禁用！";
        }else if("500".equals(error)){
            msg="系统繁忙！";
        }
        model.addAttribute("msg", msg);
        return "/login/login.html";
    }
//服务条款
    @RequestMapping(value="/clause")
    public String clause(){

        return "/login/terms.html";
    }
    /**
     *
     * @方法功能说明：验证码生成
     * @修改时间：2017-07-25 20:34:47
     * @修改内容：
     * @参数：
     * @return:
     * @throws
     */
    @RequestMapping(value="/valid-code-image.jpg")
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        // 生成验证码
        String capText = captchaProducer.createText();
        session.setAttribute(LM_SESSION_VALID_CODE_KEY, capText);
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            ImageIO.write(bi, "jpg", out);
            out.flush();
        } finally {
            if (out != null) {
				out.close();
			}
        }
    }

    /**
     *
     * @方法功能说明：校验验证码
     * @修改内容：
     * @参数：@param request
     * @参数：@param validCode
     * @参数：@return
     * @return:boolean
     * @throws
     */
    protected boolean validCodeCheck(HttpServletRequest request, String validCode) {
        if (validCode == null) {
			return false;
		}

        String sessionValidCode = (String) request.getSession().getAttribute(LM_SESSION_VALID_CODE_KEY);
        request.getSession().removeAttribute(LM_SESSION_VALID_CODE_KEY);

        if (sessionValidCode == null) {
			return false;
		}

        // 匹配验证码
        if (StringUtils.equalsIgnoreCase(validCode, sessionValidCode)) {
			return true;
		}

        return false;
    }

    /**
     *
     * @方法功能说明：退出
     * @参数：@param request
     * @参数：@param response
     * @参数：@param model
     * @参数：@throws IOException
     * @return:void
     * @throws
     */
    @RequestMapping(value = "/out")
    public void logout(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
        request.getSession().removeAttribute(Constants.SESSION_USER_KEY);
        Session session = Jurisdiction.getSession();
		session.removeAttribute(com.nhjf.common.Constants.USER_INFO);
		session.removeAttribute("resourceList");
		Cookie[] cookies = request.getCookies();//获取cookie
		for (Cookie cookie: cookies) {
	        if ("loginToken".equals(cookie.getName())) {
		        cookie.setMaxAge(0);
		        cookie.setPath("/");
		        response.addCookie(cookie);
	        }
		}
		//shiro销毁登录
//		Subject subject = SecurityUtils.getSubject(); 
//		subject.logout();
        response.sendRedirect(request.getContextPath()+"/login");
    }

    /**
     * 
     * @方法功能说明：登陆校验
     * @修改者名字：龚一凡
     * @修改内容：
     * @参数：
     * @return:
     * @throws
     */
    @RequestMapping(value="/check")
    public String loginCheck(HttpServletRequest request, HttpServletResponse response, Model model,
                           @RequestParam(value="loginName", required=false) String loginName,
                           @RequestParam(value = "password", required = false) String password,
                           @RequestParam(value = "validcode", required = false) String validcode) throws IOException{
    	  
     

	    String code  =  "1";
	    String salt="xHellxo110x";
//		String message = "" ;
		Session session = Jurisdiction.getSession();
				try {
					if (StringUtils.isEmpty(loginName)) {
						
//						response.sendRedirect(request.getContextPath()+"/login");
						String error="2";
						return index(request, model, error);
					}
				 
				   
				   //判断用户名是否包含除字母数字的其他字符
				   boolean b = Pattern.matches("^[A-Za-z0-9]+$", loginName);
				   if(!b){
					   code = "7";
						String error="2";
						return index(request, model, error);
				   }
				   
				   //如果用户输入恶意长度的登录名，则直接弹出错误信息
				   if(loginName != null && loginName.length() > 20){
					   code="6";
						String error="2";
						return index(request, model, error);
				   }
				if (StringUtils.isEmpty(password)) {
					String error="2";
					return index(request, model, error);
				}
				if(validCodeCheck(request, validcode)) {
					
				}else {
					String error="1";
					return index(request, model, error);
				}
		    	UserQo qo=new UserQo();
		    	qo.setUserName(loginName);
		    	qo.setSeachRole(true);
		    	qo.setItsusableornot(1);
		    	Encrypt encrypt=new Encrypt();
		    	
		    	User user=userService.queryUnique(qo);

	                Object   dateObj  = session.getAttribute("visitorDate");
	                Object  visitorCountObj =session.getAttribute("visitorCount");
	                int   visitorCount  =visitorCountObj==null?0:Integer.parseInt(visitorCountObj.toString());
	                Long dateLong = dateObj==null?0:Long.valueOf(dateObj.toString());
	                session.removeAttribute("visitorDate");
	                session.setAttribute("visitorDate",System.currentTimeMillis());
	                session.setAttribute("visitorCount",visitorCount=visitorCount+1);
	                
//	                if(dateLong==null){
//	                	code = "1" ;
//	                }else if(((System.currentTimeMillis()-dateLong)/1000)<=1){
//	                	code = "2" ; 
//	                }else if(LoginNum.CheckNum(loginName) == false){
//	                	code = "3" ; 
//	                }
	              
	                if(user!=null){
	    		    	if(user.getUserPassword()!=null) {
//	    		    		if(MD5.checkPwd(password, user.getUserPassword())) {
//	    		    			userLoginLogQo.setUserid(user.getId());
//	    		    		}else {
//	    		    			user=null;
//	    		    			code="2";
//	    		    		}
	    		    		String sha256PassWord=encrypt.SHA256(user.getUserPassword()+salt);
	    		    		if(sha256PassWord.equals(password)) {
	    		    			
	    		    		}else {
		    		    			user=null;
		    		    			code="2";

	    		    		}
	    		    	}else {
	    		    		user=null;
	    		    		code="2";
	    		    	}
	    			    	
	                	
	                	
	                	
	                }
	                if(user==null){

	    				if("1".equals(code)){
	    					code= "5" ;

	    				}
	    				
	                }else if("1".equals(code)){
	                	
	            		Cookie cookie = request.getCookies()[0];//获取cookie
	            		cookie.setMaxAge(0);//让cookie过期
	    				
	                }
					
				if (user != null&&"1".equals(code)) {
					 //登录成功之后获取头部
			    	ResourceQo resourceQo=new ResourceQo();
			    	resourceQo.setUserId(user.getId());
			    	resourceQo.setParentId(1L);
			    	List<Resource>	reslist=resourceService.queryList(resourceQo);//
			    	for(Resource res:reslist) {
				    	ResourceQo rQo=new ResourceQo();
				    	rQo.setUserId(user.getId());
				    	rQo.setParentId(res.getId());
				    	List<Resource>	rlist=resourceService.queryList(rQo);//
				    	res.setResourceList(rlist);
			    	}
			    	ResourceQo resourceQoall=new ResourceQo();
			    	resourceQoall.setUserId(user.getId());
			    	List<Resource>	reslistall=resourceService.queryList(resourceQoall);
			    	session.setAttribute("resourceList",reslistall);

//	    			List<Resource>	reslist=resourceService.lookResource(user.getId().toString(), "");
	//    			reslist = filterMenu(reslist);
	    			
	    			/***异常订单提醒add by Daven 2016-08-17***/
	    			//当前登录人的角色
	    			Set<Role> uRoles = user.getRoleList();
	    		
	    			Iterator<Role> iter = uRoles.iterator();
	    			Role role=new Role();
	    			while(iter.hasNext()) {
	    				role=iter.next();
	    				break;
	    			}
	    			if(role==null||role.getId()==4L) {
						String error="3";
						return index(request, model, error);
	    			}
	    			/****add by Daven end ***/
	    			String ipaddress=IPTool.getInstance().getIpAddr(request);

	                session.setAttribute(com.nhjf.common.Constants.USER_INFO,user);
	                session.setAttribute("l", 1);
	                request.setAttribute("logf", "yes");
	                session.setAttribute("reslist",reslist);
	                AdminSession entityadminSession=new AdminSession();
	                entityadminSession.setId(UUID.randomUUID().toString().replaceAll("-", ""));
	                entityadminSession.setLoginName(loginName);
	                String adminSessiontoken=salts;
	                adminSessiontoken+="@#"+loginName;
	                Date todayTime=new Date();
	                SimpleDateFormat dateFormat = new SimpleDateFormat(
	                        "yyyy-MM-dd");
	                SimpleDateFormat dateFormat1 = new SimpleDateFormat(
	                        "yyyy-MM-dd HH:mm:ss");
	                adminSessiontoken+="@#"+dateFormat.format(todayTime);
	                adminSessiontoken+="@#"+ipaddress;
	                Calendar c = Calendar.getInstance();  
	                c.setTime(todayTime); 
	                c.add(Calendar.MINUTE,45 );
	                entityadminSession.setToken(MD5.MD5Encode(adminSessiontoken));
	                entityadminSession.setExpiryTime(c.getTime());
	                AdminSessionQo adminSessionQo=new AdminSessionQo();
	                adminSessionQo.setLoginName(loginName);
	                AdminSession adminSession=adminSessionService.queryUnique(adminSessionQo);
	                if(adminSession!=null) {
	                	entityadminSession.setId(adminSession.getId());
	                	adminSessionService.update(entityadminSession);
	                }else {
	                	adminSessionService.save(entityadminSession);
	                }
	                Cookie userCookie=new Cookie("loginToken",MD5.MD5Encode(adminSessiontoken)); 

	                userCookie.setMaxAge(-10);   
	                userCookie.setPath("/");
	                response.addCookie(userCookie);
	                //异常提醒订单数量
	                
					//shiro加入身份验证
					org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject(); 
				    org.apache.shiro.authc.UsernamePasswordToken token = new org.apache.shiro.authc.UsernamePasswordToken(loginName, password); 
				    try {
				    	final LinkedHashMap<Object, Object> attributes = new LinkedHashMap<Object, Object>();
				    	final Collection<Object> keys = session.getAttributeKeys();
	                    for (Object key : keys) {
	                    	final Object value = session.getAttribute(key);
	                    	if (value != null) {
	                    		attributes.put(key, value); 
	                    	}
	                    }
	                    session.stop();
				    	subject.login(token);
				    	session = subject.getSession();
				    	for (final Object key : attributes.keySet()) { 
				    		session.setAttribute(key, attributes.get(key)); 
				    	}
				    } catch (org.apache.shiro.authc.AuthenticationException e) { 
				    	e.printStackTrace();
				    }
				} else {
//					request.setAttribute("logf", "no");
//					request.setAttribute("code", code);
//					response.sendRedirect(request.getContextPath()+"/login");
//					return;
					String error="2";
					return index(request, model, error);
				}
	
			} catch (Exception e) {
				e.printStackTrace();
				this.logwrite(this.getClass(), e.getMessage());
			}
		//}
		
				response.sendRedirect(request.getContextPath()+"/home");
				return null;
    }
	@Override
	public  void logwrite(Class clazz, String log) {
		com.nhjf.common.util.LogMessage.logwrite(clazz, log);
	}
}
